#include "../src/Log.h"
#include <chrono>
using namespace std;
/*
    测试环境
    CPU：Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz   2.11 GHz
    RAM：8GB
    OS：ubuntu-20.04TLS虚拟机（2CPU核⼼/2GB内存）
*/

/*
性能测试
    1、测试同步&异步日志器各自性能----->分为多线程和单线程性能测试
    2、计算每秒输出量=日志数量/总耗时
    3、计算每秒输出大小=日志数量*单条日志大小/总耗时
    4、异步线程只考虑写入内存总耗时，不考虑实际落地时间

*/
void bench(const string &Logger_name, size_t thr_count, size_t msg_count, size_t msg_size)
{
    // 1、获取日志器
    LogManager::Logger::ptr logger = Log::getLogger(Logger_name);
    if (logger.get() == nullptr)
        return;
    cout << "测试日志:" << msg_count << "条, 总大小:" << (msg_count * msg_size) / 1024 << "KB" << endl;
    // 2、组织制定长度日志消息
    string msg(msg_size - 1, 'A');
    // 3、创建指定数量线程
    vector<thread> _threads(thr_count);         // 存放线程
    vector<double> cost_array(thr_count);       // 存放每个线程输出日志花费时间
    size_t msg_per_thr = msg_count / thr_count; // 每个线程输出日志条数
    for (int i = 0; i < thr_count; i++)
    {
        _threads[i] = thread([&, i]()
                             {
                                 // 4、线程内部开始计时
                                 auto begin = chrono::high_resolution_clock::now();
                                 // 5、开始循环写日志
                                 for (int j = 0; j < msg_per_thr; j++)
                                 {
                                     logger->fatal("%s", msg.c_str());
                                 }
                                 // 6、线程输出结束时间
                                 auto end = chrono::high_resolution_clock::now();
                                 chrono::duration<double> cost = end - begin;
                                 cost_array[i] = cost.count();
                                 cout<<"\t线程"<<i<<":"<<"\t输出数量:"<<msg_per_thr<<", 消耗时间:"<<cost.count()<<"s"<<endl; });
    }
    for (int i = 0; i < thr_count; i++)
    {
        _threads[i].join();
    }
    // 7、计算总耗时
    double max_cost = 0;
    for (auto &x : cost_array)
        max_cost = max(max_cost, x);
    size_t msg_pre_sec = msg_count / max_cost;                        // 计算每秒输出量
    size_t size_pre_sec = (msg_count * msg_size) / (max_cost * 1024); // 计算每秒输出大小
    // 8、打印输出
    cout << "\t总耗时:" << max_cost << endl;
    cout << "\t每秒输出日志数量:" << msg_pre_sec << "条" << endl;
    cout << "\t每秒输出日志大小:" << size_pre_sec << "KB" << endl;
}
void sync_bench()
{
    unique_ptr<LogManager::LoggerBuilder> loggerbuild(new LogManager::GlobalLoggerBuilder());
    loggerbuild->buildLoggerName("sync_logger");
    loggerbuild->buildLoggerLevel(Level::LogLevel::DEBUG);
    loggerbuild->buildLoggerType(LogManager::LoggerType::SYNC_Logger);
    loggerbuild->buildSink<Sink::FileSink>("./logfile/Sync.log");
    loggerbuild->build();
    // 同步模式下单线程测试
    bench("sync_logger", 1, 2000000, 100);
    // 同步模式下多线程测试
    // bench("sync_logger", 3, 2000000, 100);
}
void async_bench()
{
    unique_ptr<LogManager::LoggerBuilder> loggerbuild(new LogManager::GlobalLoggerBuilder());
    loggerbuild->buildLoggerName("async_logger");
    loggerbuild->buildLoggerLevel(Level::LogLevel::DEBUG);
    loggerbuild->buildLoggerType(LogManager::LoggerType::ASYNC_Logger);
    loggerbuild->buildUnSafeLopperType(); // 开启非安全模式，缓冲区满了也不需要阻塞等待
    loggerbuild->buildSink<Sink::FileSink>("./logfile/Async.log");
    loggerbuild->build();
    // 异步模式下单线程测试
    // bench("async_logger", 1, 2000000, 100);
    // 同步模式下多线程测试
    bench("async_logger", 3, 2000000, 100);
}
int main()
{
    // sync_bench();
    async_bench();
    return 0;
}
